from django.db import models
from django.contrib.auth.models import User
from cryptography.fernet import Fernet
from django.conf import settings
import json


class DeviceBrand(models.Model):
    """设备品牌模型"""
    name = models.CharField(max_length=50, unique=True, verbose_name="品牌名称")
    api_endpoint = models.URLField(verbose_name="API端点")
    auth_type = models.CharField(max_length=20, verbose_name="认证类型")
    logo = models.ImageField(upload_to='brand_logos/', blank=True, null=True, verbose_name="品牌Logo")
    description = models.TextField(blank=True, verbose_name="品牌描述")
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    class Meta:
        verbose_name = "设备品牌"
        verbose_name_plural = "设备品牌"
        ordering = ['name']

    def __str__(self):
        return self.name


class DeviceType(models.Model):
    """设备类型模型"""
    CATEGORY_CHOICES = [
        ('air_conditioner', '空调'),
        ('refrigerator', '冰箱'),
        ('washing_machine', '洗衣机'),
        ('water_heater', '热水器'),
        ('smart_light', '智能灯具'),
        ('robot_vacuum', '扫地机器人'),
        ('smart_speaker', '智能音箱'),
        ('smart_tv', '智能电视'),
        ('other', '其他'),
    ]
    
    name = models.CharField(max_length=50, verbose_name="设备类型名称")
    category = models.CharField(max_length=30, choices=CATEGORY_CHOICES, verbose_name="设备分类")
    supported_commands = models.JSONField(default=list, verbose_name="支持的命令列表")
    icon = models.CharField(max_length=50, blank=True, verbose_name="图标类名")
    description = models.TextField(blank=True, verbose_name="类型描述")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")

    class Meta:
        verbose_name = "设备类型"
        verbose_name_plural = "设备类型"
        ordering = ['category', 'name']

    def __str__(self):
        return f"{self.get_category_display()} - {self.name}"


class Device(models.Model):
    """设备模型"""
    STATUS_CHOICES = [
        ('online', '在线'),
        ('offline', '离线'),
        ('error', '故障'),
        ('maintenance', '维护中'),
    ]
    
    ROOM_CHOICES = [
        ('living_room', '客厅'),
        ('bedroom', '卧室'),
        ('kitchen', '厨房'),
        ('bathroom', '卫生间'),
        ('study', '书房'),
        ('balcony', '阳台'),
        ('other', '其他'),
    ]

    name = models.CharField(max_length=100, verbose_name="设备名称")
    brand = models.ForeignKey(DeviceBrand, on_delete=models.CASCADE, verbose_name="设备品牌")
    device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE, verbose_name="设备类型")
    device_id = models.CharField(max_length=100, verbose_name="设备ID")
    room = models.CharField(max_length=50, choices=ROOM_CHOICES, verbose_name="房间位置")
    status = models.JSONField(default=dict, verbose_name="设备状态")
    connection_status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='offline', verbose_name="连接状态")
    last_seen = models.DateTimeField(blank=True, null=True, verbose_name="最后在线时间")
    owner = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="所有者")
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    class Meta:
        verbose_name = "设备"
        verbose_name_plural = "设备"
        ordering = ['-updated_at']
        unique_together = ['brand', 'device_id', 'owner']

    def __str__(self):
        return f"{self.name} ({self.brand.name})"

    @property
    def is_online(self):
        """检查设备是否在线"""
        return self.connection_status == 'online'

    def update_status(self, new_status):
        """更新设备状态"""
        self.status.update(new_status)
        self.save(update_fields=['status', 'updated_at'])


class PlatformCredential(models.Model):
    """平台账号凭证模型"""
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户")
    brand = models.ForeignKey(DeviceBrand, on_delete=models.CASCADE, verbose_name="品牌")
    platform_username = models.CharField(max_length=100, verbose_name="平台用户名")
    platform_password = models.CharField(max_length=255, verbose_name="加密后的密码")
    access_token = models.TextField(blank=True, null=True, verbose_name="访问令牌")
    refresh_token = models.TextField(blank=True, null=True, verbose_name="刷新令牌")
    token_expires_at = models.DateTimeField(blank=True, null=True, verbose_name="令牌过期时间")
    additional_data = models.JSONField(default=dict, verbose_name="额外的认证数据")
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    
    class Meta:
        verbose_name = "平台凭证"
        verbose_name_plural = "平台凭证"
        unique_together = ['user', 'brand']
        ordering = ['-updated_at']

    def __str__(self):
        return f"{self.user.username} - {self.brand.name}"
        
    def save(self, *args, **kwargs):
        """保存时加密密码"""
        if self.platform_password and not self.platform_password.startswith('enc_'):
            cipher_suite = Fernet(settings.ENCRYPTION_KEY)
            encrypted_password = cipher_suite.encrypt(self.platform_password.encode())
            self.platform_password = 'enc_' + encrypted_password.decode()
        super().save(*args, **kwargs)
    
    def get_decrypted_password(self):
        """获取解密后的密码"""
        if self.platform_password.startswith('enc_'):
            cipher_suite = Fernet(settings.ENCRYPTION_KEY)
            encrypted_password = self.platform_password[4:]  # 去掉'enc_'前缀
            return cipher_suite.decrypt(encrypted_password.encode()).decode()
        return self.platform_password

    def is_token_valid(self):
        """检查令牌是否有效"""
        if not self.token_expires_at:
            return False
        from django.utils import timezone
        return timezone.now() < self.token_expires_at


class DeviceCommand(models.Model):
    """设备命令记录模型"""
    COMMAND_STATUS_CHOICES = [
        ('pending', '待执行'),
        ('executing', '执行中'),
        ('success', '成功'),
        ('failed', '失败'),
        ('timeout', '超时'),
    ]

    device = models.ForeignKey(Device, on_delete=models.CASCADE, verbose_name="目标设备")
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="执行用户")
    command = models.CharField(max_length=100, verbose_name="命令名称")
    parameters = models.JSONField(default=dict, verbose_name="命令参数")
    status = models.CharField(max_length=20, choices=COMMAND_STATUS_CHOICES, default='pending', verbose_name="执行状态")
    result = models.JSONField(default=dict, verbose_name="执行结果")
    error_message = models.TextField(blank=True, verbose_name="错误信息")
    executed_at = models.DateTimeField(blank=True, null=True, verbose_name="执行时间")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")

    class Meta:
        verbose_name = "设备命令"
        verbose_name_plural = "设备命令"
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.device.name} - {self.command} ({self.get_status_display()})"
